﻿using RpcCentral.Collect;
using RpcCentral.Collect.Controller;
using RpcCentral.Collect.Model;
using RpcCentral.Model;
using RpcCentral.Model.DB;
using RpcCentral.Service.Interface;
using WeDonekRpc.Model;

namespace RpcCentral.Service.Service
{
    internal class ContrainerLoginService : IContrainerLoginService
    {
        private readonly IRpcTokenCollect _TokenCollect;
        private readonly IRpcMerCollect _MerCollect;
        private readonly IContainerGroupCollect _ContainerGroup;
        private readonly IContainerCollect _Container;
        private readonly IRpcServerCollect _Server;
        private readonly IRpcServerStateCollect _ServerState;
        private readonly ISystemTypeCollect _SystemType;
        public ContrainerLoginService (IRpcTokenCollect token,
            ISystemTypeCollect systemType,
            IContainerGroupCollect containerGroup,
            IRpcMerCollect mer,
            IContainerCollect container,
            IRpcServerCollect server,
            IRpcServerStateCollect serverState)
        {
            this._ContainerGroup = containerGroup;
            this._Container = container;
            this._SystemType = systemType;
            this._ServerState = serverState;
            this._Server = server;
            this._MerCollect = mer;
            this._TokenCollect = token;
        }

        public RpcServerLoginRes Login (RpcServerLogin login, string remoteIp)
        {
            RpcTokenCache token = this._TokenCollect.Get(login.AccessToken);
            RpcMer mer = this._MerCollect.GetMer(token.RpcMerId);
            RemoteServerLogin param = login.ServerLogin;
            SystemTypeDatum systemType = this._SystemType.GetSystemType(param.SystemType);
            ContainerInfo con = param.Container;
            BasicContainerGroup group = this._ContainerGroup.GetGroup(con.Number);
            long conId = this._Container.RegContainer(new ContrainerLogin
            {
                ContGroupId = group.Id,
                ContrainerId = con.ContainerId,
                GroupId = systemType.GroupId,
                Process = param.Process,
                RegionId=group.RegionId,
                RpcMerId = mer.Id,
                ApiVer = login.ApiVer,
                ServerIp = remoteIp,
                LocalMac = param.ServerMac,
                ServerPort = con.DefPort ?? systemType.DefPort,
                SystemName = systemType.SystemName,
                ServiceType = systemType.ServiceType,
                SystemType = systemType.Id
            });
            RpcServerController rpcServer = this._Server.FindRpcServer(conId);
            this._ServerState.SyncRunState(rpcServer.ServerId, param.Process);
            if (rpcServer.ServerOnline(remoteIp, login.ApiVer))
            {
                this._TokenCollect.SetConServerId(token, rpcServer.ServerId);
            }
            RemoteServerModel server = rpcServer.Server;
            return new RpcServerLoginRes
            {
                OAuthConfig = new RpcConfig
                {
                    AllowConIp = mer.AllowServerIp
                },
                ServerConfig = new RpcServerConfig
                {
                    Name = server.ServerName,
                    IsEnablePipe = false,
                    ConfigPrower = server.ConfigPrower,
                    RegionId = server.RegionId,
                    ServerId = rpcServer.ServerId,
                    ServerPort = server.ServerPort,
                    ServerIp = server.ServerIp,
                    ContainerGroup = group.Id,
                    RecoveryLimit = server.RecoveryLimit,
                    RecoveryTime = server.RecoveryTime,
                    GroupId = server.GroupId,
                    GroupTypeVal = rpcServer.GroupTypeVal,
                    ServiceState = server.ServiceState,
                    SystemType = server.SystemType,
                    PublicKey = server.PublicKey,
                    VerNum = server.VerNum
                }
            };
        }
    }
}
